# -*- coding: utf-8 -*-

import pymysql
import pymysql.cursors
import time
from twisted.enterprise import adbapi
from lib.ucloud.logger import logger

from src.sshconn.ssh_conn import singleton


@singleton
class MysqlTwistedPipelineInsert(object):
    """
    异步写入mysql
    """
    def __init__(self):
        self.dbpool = self.from_settings()
        self.failureTime = 2592000  # 30天

    def from_settings(self):
        # ALTER TABLE local_db.ucloud_t  ADD INDEX index_ucloud_t (id, CreateTime, download_state);
        dbparms = dict(
            host='127.0.0.1',
            db='local_db',
            user='root',
            password='12345678',
            port=3306,
            charset='utf8mb4',
            cursorclass=pymysql.cursors.DictCursor,
            use_unicode=True
        )
        return adbapi.ConnectionPool("pymysql", **dbparms)

    def process_truncate(self):
        query = self.dbpool.runInteraction(self.do_truncate)
        query.addErrback(self.handle_truncate_error)

    def do_truncate(self, cursor):
        truncate_sql = "TRUNCATE ucloud_t"
        cursor.execute(truncate_sql)

    def handle_truncate_error(self, failure):
        logger.info('handle_truncate_error error {failure}'.format(failure=failure))

    def process_item(self, item):
        """
        对外提供调用方法
        """
        query = self.dbpool.runInteraction(self.do_insert, item)
        query.addErrback(self.handle_error, item)

    def handle_error(self, failure, item):
        # 处理异步插入异常
        logger.info('error {failure} item {item}'.format(failure=failure, item=item))

    def do_insert(self, cursor, item):
        """
        插入
        """
        insert_sql = """
            insert into ucloud_t(BucketName, FileName, Hash, MimeType, 
            first_object, Size, CreateTime, ModifyTime, download_state, local_file_path)
            values (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
        """
        # 判断是否过期 CreateTime 时间戳是秒
        download_state = 0
        if time.time() - item.get("CreateTime", 0) < self.failureTime:
            # 未过期
            download_state = 0
        else:
            # 过期
            download_state = 2
        args = (item.get("BucketName", ""), item.get("FileName", ""), item.get("Hash", ""), item.get("MimeType", ""),
                item.get("first_object", ""), item.get("Size", 0), item.get("CreateTime", 0), item.get("ModifyTime", 0),
                download_state, '')
        cursor.execute(insert_sql, args)

    def process_item_delete(self, item):
        """
        对外提供调用方法 更新
        """
        query = self.dbpool.runInteraction(self.do_delete, item)
        query.addErrback(self.handle_delete_error, item)

    def handle_delete_error(self, failure, item):
        # 处理异步插入异常
        logger.info('error {failure} item {item}'.format(failure=failure, item=item))

    def do_delete(self, cursor, item):
        """
        update
        """
        delete_sql = """
            DELETE FROM ucloud_t where id = %s
        """
        args = (item.get("id", 0),)
        cursor.execute(delete_sql, args)

    def process_item_update(self, item):
        """
        对外提供调用方法 更新
        """
        query = self.dbpool.runInteraction(self.do_update, item)
        query.addErrback(self.handle_update_error, item)

    def handle_update_error(self, failure, item):
        # 处理异步插入异常
        logger.info('error {failure} item {item}'.format(failure=failure, item=item))

    def do_update(self, cursor, item):
        """
        update
        """
        update_sql = """
            UPDATE ucloud_t SET download_state = %s where id = %s
        """
        args = (item.get("download_state", 2), item.get("id", 0))
        cursor.execute(update_sql, args)

    def process_item_path_update(self, item):
        """
        对外提供调用方法 更新
        """
        query = self.dbpool.runInteraction(self.do_path_update, item)
        query.addErrback(self.handle_path_update_error, item)

    def handle_path_update_error(self, failure, item):
        # 处理异步插入异常
        logger.info('error {failure} item {item}'.format(failure=failure, item=item))

    def do_path_update(self, cursor, item):
        """
        update
        """
        update_sql = """
            UPDATE ucloud_t SET download_state = %s, local_file_path= %s where id = %s
        """
        args = (item.get("download_state", 0), item.get("local_file_path", ""), item.get("id", 0))
        cursor.execute(update_sql, args)


def truncate_table():
    MysqlTwistedPipelineInsert().process_truncate()


def insert_item(item):
    MysqlTwistedPipelineInsert().process_item(item)


def update_item(item):
    MysqlTwistedPipelineInsert().process_item_update(item)


def update_path_item(item):
    MysqlTwistedPipelineInsert().process_item_path_update(item)


def delete_item(item):
    MysqlTwistedPipelineInsert().process_item_delete(item)
